package com.wstuo.common.tools.dao;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.wstuo.common.tools.dto.TaskDTO;
import com.wstuo.common.tools.dto.TaskQueryDTO;
import com.wstuo.common.tools.entity.Task;
import com.wstuo.common.dao.BaseDAOImplHibernate;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.util.DaoUtils;
import com.wstuo.common.util.StringUtils;

/**
 * 任务DAO类
 * 
 * @author QXY
 * 
 */
public class TaskDAO extends BaseDAOImplHibernate<Task> implements ITaskDAO {

	/**
	 * 根据任务ID批量获取其中是普通任务的ID；
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Long> findDeleteTask(Long[] ids) {
		List<Long> list = null;
		if (ids != null && ids.length > 0) {
			String hql = "SELECT tk.taskId FROM Task tk LEFT JOIN tk.taskCycle tc " +
					" WHERE ( tc.type IS NULL OR tc.type = :type ) " +
					" AND tk.taskId IN (:ids) ";
			list = super.getHibernateTemplate().findByNamedParam(hql
					,new String[]{"type","ids"}
					,new Object[]{"NO",ids}
			);
		}
		return list;
	}

	/**
	 * 根据任务ID批量获取其中是循环任务的ID；
	 */
	@Override
	public List<Long> findDeleteTaskCycle(Long[] ids) {
		List<Long> list = null;
		if (ids != null && ids.length > 0) {
			DetachedCriteria dc = DetachedCriteria.forClass(Task.class);
			dc.add(Restrictions.isNotNull("taskCycle"));
			dc.createAlias("taskCycle", "tc").add(Restrictions.eq("tc.type", "WEEK"));
			dc.add( Restrictions.in("taskId", ids));
			dc.setProjection( Projections.property( "taskId" ) );
			list = super.getHibernateTemplate().findByCriteria( dc );
		}
		return list;
	}

	/**
	 * 任务分页查询
	 * 
	 * @param taskQueryDto
	 * @param start
	 * @param limit
	 * @return PageDTO
	 */
	public PageDTO findPagerTaskDAO(TaskQueryDTO taskQueryDto, int start,
			int limit, String sidx, String sord) {
		DetachedCriteria dc = DetachedCriteria.forClass(Task.class);
		if (taskQueryDto != null) {
			if (StringUtils.hasText(taskQueryDto.getOwner())) {
				dc.createAlias("owner", "on")
						.add(Restrictions.eq("on.loginName",taskQueryDto.getOwner()));
			}
			if(StringUtils.hasText(taskQueryDto.getTypeDno())){
				dc.createAlias("type", "daitems")
				.add(Restrictions.eq("daitems.dno",taskQueryDto.getTypeDno()));
			}
			if (StringUtils.hasText(taskQueryDto.getTitle())) {
				dc.add(Restrictions.like("title", taskQueryDto.getTitle(),
						MatchMode.ANYWHERE));
			}

			if (taskQueryDto.getTaskStatus() != null) {
				dc.add(Restrictions.eq("taskStatus",
						taskQueryDto.getTaskStatus()));
			}
			// 时间搜索
            if (taskQueryDto.getStartTime() != null && taskQueryDto.getEndTime()!=null) {
            	Calendar endTimeCl=new GregorianCalendar();
            	endTimeCl.setTime(taskQueryDto.getEndTime());
            	endTimeCl.set(Calendar.DATE, endTimeCl.get(Calendar.DATE));
            	if(taskQueryDto.getStartTime().equals(taskQueryDto.getEndTime()))
            		endTimeCl.add(Calendar.DATE,1);
            	dc.add(Restrictions.and(
        				Restrictions.le("startTime", endTimeCl.getTime()),
        				Restrictions.ge("endTime", taskQueryDto.getStartTime())
        				));
            	
            }else if (taskQueryDto.getStartTime() != null) {
                dc.add(Restrictions.ge("startTime", taskQueryDto.getStartTime()));
            }else if (taskQueryDto.getEndTime()!=null) {
            	Calendar endTimeCl=new GregorianCalendar();
            	endTimeCl.setTime(taskQueryDto.getEndTime());
            	endTimeCl.set(Calendar.DATE, endTimeCl.get(Calendar.DATE));
            	endTimeCl.add(Calendar.DATE,1);
                dc.add(Restrictions.le("endTime",endTimeCl.getTime()));
            }

		}
		// 排序
		dc = DaoUtils.orderBy(sidx, sord, dc);
		return super.findPageByCriteria(dc, start, limit);
	}

	/**
	 * 查询我的全部任务
	 * 
	 * @param qdto
	 *            TaskQueryDTO
	 * @return List<Task>
	 */
	@SuppressWarnings("unchecked")
	public List<Task> findMyAllTask(TaskQueryDTO qdto) {

		final DetachedCriteria dc = DetachedCriteria.forClass(Task.class);
		if (StringUtils.hasText(qdto.getOwner())) {
			dc.createAlias("owner", "on").add(
					Restrictions.eq("on.loginName", qdto.getOwner()));
		}
		if (StringUtils.hasText(qdto.getNoOwner())) {
			dc.createAlias("owner", "on").add(
					Restrictions.not(Restrictions.eq("on.loginName", qdto.getNoOwner())));
		}
		if (qdto.getOwnerNo()!=null) {
			dc.createAlias("owner", "on").add(
					Restrictions.eq("on.userId", qdto.getOwnerNo()));
		}
		if (StringUtils.hasText(qdto.getTitle())) {
			dc.add(Restrictions.like("title", qdto.getTitle(),
					MatchMode.ANYWHERE));
		}
		if (qdto.getTaskStatus() != null) {
			dc.add(Restrictions.eq("taskStatus", qdto.getTaskStatus()));
		}
		if(StringUtils.hasText(qdto.getTypeDno())){
			dc.createAlias("type", "taskType").add(
					Restrictions.eq("taskType.dno", qdto.getTypeDno()));
		}
		if(qdto.getDcode()!=null){
			dc.createAlias("type", "taskType").add(
					Restrictions.eq("taskType.dcode", qdto.getDcode()));
		}
		// 时间搜索
		if (qdto.getStartTime() != null && qdto.getEndTime() == null) {
			dc.add(Restrictions.ge("startTime", qdto.getStartTime()));
		}else if (qdto.getStartTime() == null && qdto.getEndTime() != null) {

			Calendar endTimeCl = new GregorianCalendar();
			endTimeCl.setTime(qdto.getEndTime());
			endTimeCl.set(Calendar.DATE, endTimeCl.get(Calendar.DATE) + 1);

			dc.add(Restrictions.le("endTime", endTimeCl.getTime()));
		}else if (qdto.getStartTime() != null && qdto.getEndTime() != null) {
			Calendar endTimeCl = new GregorianCalendar();
			endTimeCl.setTime(qdto.getEndTime());
			if(StringUtils.hasText(qdto.getTypeDno())&&qdto.getTypeDno().equals("task_workforce")){
				endTimeCl.set(Calendar.DATE, endTimeCl.get(Calendar.DATE));
			}else{
				endTimeCl.set(Calendar.DATE, endTimeCl.get(Calendar.DATE)+1);
			}
			dc.add(Restrictions.and(
				Restrictions.le("startTime", endTimeCl.getTime()),
				Restrictions.ge("endTime", qdto.getStartTime())));
		}

		return super.getHibernateTemplate().findByCriteria(DaoUtils.orderBy(qdto.getSidx(), qdto.getSord(), dc));
	};

	/**
	 * 查询指定时间段任务
	 * 
	 * @param taskDTO
	 * @return boolean
	 */
	@SuppressWarnings("unchecked")
	public boolean findSameTimeTask(TaskDTO taskDTO) {
		boolean result = false;
		if (taskDTO.getStartTime() != null && taskDTO.getEndTime() != null&& taskDTO.getOwner() != null&&taskDTO.getTaskStatus()!=null&& taskDTO.getTaskStatus() != 2) {
			// 完成状态
			String hql = " from Task tk where tk.owner.loginName=? and (tk.startTime between ? and ? or tk.endTime between ? and ?) and tk.taskStatus!=2";
			// System.err.println(taskDTO.getTaskId()+"----------");
			if (taskDTO.getTaskId() != null&&taskDTO.getTaskId() != 0) // will
				hql += " and taskId!=" + taskDTO.getTaskId();
			List<Task> tasks = super.getHibernateTemplate().find(hql,
					taskDTO.getOwner(), taskDTO.getStartTime(),
					taskDTO.getEndTime(), taskDTO.getStartTime(),
					taskDTO.getEndTime());
			if (tasks != null && tasks.size() > 0) {
				result = true;
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public List<Task> findTimeRangeTask(TaskDTO taskDTO) {
		List<Task> tasks = null;
		if (taskDTO.getStartTime() != null && taskDTO.getEndTime() != null
				//开始时间必须在结束时间之前
				&& taskDTO.getStartTime().before( taskDTO.getEndTime() ) ) {
			//"2015-07-17 12:19:24" < endTime AND "2015-07-17 14:19:24" > startTime
			String hql = " from Task tk where ? < tk.endTime and ? > tk.startTime" +
					" and tk.type.dno = ? ";
			tasks = super.getHibernateTemplate().find(hql, taskDTO.getStartTime(),
					taskDTO.getEndTime(),taskDTO.getDno());
		}
		return tasks;
	}

	@Override
	public void endTask(Long[] ids) {
		if (ids != null && ids.length > 0) {
			String updaCycleHql = "update TaskCycle tc set tc.type = :type where id in(:ids)";
			Query updaCycleQuery = getSession().createQuery(updaCycleHql);
			updaCycleQuery.setParameter("type", "NO");
			updaCycleQuery.setParameter("ids", ids);
			updaCycleQuery.executeUpdate();
			
			String updaTaskHql = "update Task tk set tk.endTime = :date where id in(:ids)";
			Query updaTaskQuert = getSession().createQuery(updaTaskHql);
			updaTaskQuert.setParameter("date", new Date() );
			updaTaskQuert.setParameter("ids", ids);
			updaTaskQuert.executeUpdate();
			
		}
	}

}
